package com.fessc.develop.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.Scanner;

public class DateUtil {
    private static final Logger logger = LoggerFactory.getLogger(DateUtil.class);

    public static String DATE_FORMAT = "yyyy-MM-dd";

    public static String YEAR_MONTH_FORMAT = "yyyy-MM";

    public static String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    public static String DATE_TIME_HM_FORMAT = "yyyyMMddHHmmss";

    public static String DATE_TIME_MS_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";

    public static String YEAR_FORMAT = "yyyy";

    public static String MONTH_FORMAT = "MM";

    public static String DATE_UTF8_FORMAT = "yyyy年MM月dd日";

    public static String DATE_SIMP_FORMAT = "yyyyMMdd";

    public static String MONTH_DAY_FORMAT = "MM-dd";

    public static String CURRENT_TIMESTAMP = "yyyyMMddHHmmssFFF";

    /**
     * 获取当前年份(格式：yyyy)
     *
     * @return
     */
    public static String getCurrentYear() {

        return getCurrentDateTime(YEAR_FORMAT);
    }

    /**
     * 获取当前月份(格式：MM)
     *
     * @return
     */
    public static String getCurrentMonth() {

        return getCurrentDateTime(MONTH_FORMAT);
    }

    public static String getCurrentTimeStamp() {

        return getCurrentDateTime(CURRENT_TIMESTAMP);
    }

    /**
     * 获得当前年月
     *
     * @return
     */
    public static String getCurrentYearMonth() {

        return getCurrentDateTime(YEAR_MONTH_FORMAT);
    }

    /**
     * 获取当前日期(格式：yyyy-MM-dd)
     *
     * @return
     */
    public static String getCurrentDate() {
        return getCurrentDateTime(DATE_SIMP_FORMAT);
    }

    public static String getCurrentSimpDate() {

        return getCurrentDateTime(DATE_SIMP_FORMAT);
    }

    /**
     * 获取当前时间(格式：yyyy-MM-dd HH:mm:ss)
     *
     * @return
     */
    public static String getCurrentDateTime() {

        return getCurrentDateTime(DATE_TIME_FORMAT);
    }

    /**
     * 获取当前月日(格式：MM-dd)
     *
     * @return
     */
    public static String getCurrentMonthDay() {

        return getCurrentDateTime(MONTH_DAY_FORMAT);
    }

    /**
     * 获取指定格式的当前时间
     *
     * @param dateFormat 指定的格式
     * @return
     */
    public static String getCurrentDateTime(String dateFormat) {
        String dateStr = null;
        SimpleDateFormat df = new SimpleDateFormat(dateFormat);
        dateStr = df.format(new Date());
        return dateStr;
    }

    /**
     * 指定格式的字符串转日期
     *
     * @param dateStr    日期字符串
     * @param dateFormat 日期格式
     * @return
     */
    public static Date stringToDate(String dateStr, String dateFormat) {
        if (dateStr == null || "".equals(dateStr) || dateFormat == null || "".equals(dateFormat)) {
            return null;
        }

        Date date = null;
        SimpleDateFormat df = new SimpleDateFormat(dateFormat);
        try {
            date = df.parse(dateStr);
        } catch (ParseException e) {
            logger.error("stringToDate format error, dateStr = " + dateStr + ", dateFormat = " + dateFormat, e);
            return null;
        }
        return date;
    }

    /**
     * yyyy-MM-dd格式的字符串转日期
     *
     * @param dateStr 日期字符串
     * @return
     */
    public static Date stringToDate(String dateStr) {

        return stringToDate(dateStr, DATE_FORMAT);
    }

    /**
     * yyyy-MM-dd HH:mm:ss格式的字符串转日期
     *
     * @param dateStr 日期字符串
     * @return
     */
    public static Date stringToDateTime(String dateStr) {

        return stringToDate(dateStr, DATE_TIME_HM_FORMAT);
    }

    /**
     * 日期转字符串
     *
     * @param date
     * @param pattern
     * @return
     */
    public static String dateToString(Date date, String pattern) {
        pattern = BusiUtil.isNotNull(pattern) ? pattern : DATE_TIME_FORMAT;
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(date);
    }


    public static long getSysCurrentTimeMillis() {

        return System.currentTimeMillis();
    }

    /**
     * 获取timestamp时间戳
     *
     * @return
     */
    public static String getTimeStamp() {
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        return String.valueOf(timestamp.getTime());
    }

    /**
     * "yyyy年MM月dd日"  转格式 yyyyMMdd
     *
     * @param dateString
     * @return
     */
    public static String formatDateForStr(String dateString) {
        if (dateString == null || "".equals(dateString)) {
            return null;
        }
        SimpleDateFormat format = new SimpleDateFormat(DATE_SIMP_FORMAT);
        SimpleDateFormat format1 = new SimpleDateFormat(DATE_UTF8_FORMAT);
        try {
            Date date = format1.parse(dateString);
            return format.format(date);
        } catch (ParseException e) {
            logger.info("异常信息：" + e.getMessage());
        }
        return null;
    }

    /**
     * 获取上一个月份字符串
     *
     * @return
     */
    public static String getLastMonth() {
        SimpleDateFormat format = new SimpleDateFormat("YYYY-MM");
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date); // 设置为当前时间
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1); // 设置为上一个月
        date = calendar.getTime();
        String lastMonth = format.format(date);
        return lastMonth;
    }

    /**
     * 返回下月月份(yyyy-MM)
     *
     * @return
     */
    public static String getNextMonth(String str) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(stringToDate(str, "yyyy-MM")); // 设置为当前时间
        calendar.add(Calendar.MONTH, 1);    // 设置为下一个月
        Date date = calendar.getTime();
        String nextMonth = format.format(date);
        return nextMonth;
    }

    /**
     * 获得当前月份第一天
     */
    public static String getCurrentMonthFirstDate(String pattern) {
        pattern = BusiUtil.isNull(pattern) ? pattern : DATE_FORMAT;
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
        Date date = calendar.getTime();
        return dateFormat.format(date);
    }

    /**
     * 获得当前月份最后一天
     */
    public static String getCurrentMonthLastDate(String pattern) {
        pattern = BusiUtil.isNull(pattern) ? pattern : DATE_FORMAT;
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date date = calendar.getTime();
        return dateFormat.format(date);
    }

    /**
     * 获得指定年月的最后一天
     *
     * @param year
     * @param month
     * @param pattern
     * @return
     */
    public static String getMonthFirstDate(int year, int month, String pattern) {
        pattern = BusiUtil.isNull(pattern) ? pattern : DATE_FORMAT;
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1); //设置当前月的上一个月
        int lastDay = cal.getActualMinimum(Calendar.DATE); //获取月份中的最小值，即第一天
        cal.set(Calendar.DAY_OF_MONTH, lastDay);
        return dateFormat.format(cal.getTime());
    }

    /**
     * 获得指定年月的最后一天
     *
     * @param year
     * @param month
     * @param pattern
     * @return
     */
    public static String getMonthLastDate(int year, int month, String pattern) {
        pattern = BusiUtil.isNull(pattern) ? pattern : DATE_FORMAT;
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month); //设置当前月的上一个月
        int lastDay = cal.getActualMinimum(Calendar.DATE); //获取月份中的最小值，即第一天
        cal.set(Calendar.DAY_OF_MONTH, lastDay - 1);
        return dateFormat.format(cal.getTime());
    }

    /**
     * 根据折旧期间和折旧日期封装日期
     *
     * @param deprDate
     * @param deprDateDay
     * @return
     * @throws ParseException
     */
    public static Date handleDeprDate(String deprDate, String deprDateDay) {
        String dateStr = deprDate + (BusiUtil.isNull(deprDateDay) ? DateUtil.getCurrentMonthDay() : deprDateDay).substring(2);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = dateFormat.parse(dateStr);
        } catch (ParseException e) {
            logger.error("handleDeprDate format error, dateStr = " + dateStr + ", dateFormat = " + dateFormat, e);
            return null;
        }
        return date;
    }

    /**
     * 计算日期相加
     *
     * @param dateDate 起息日期
     * @param field    1 年份 2 月份
     * @param amount   加的数
     * @return
     */
    public static String getAddDays(String dateDate, int field, int amount) {
        try {
            DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date date = sdf.parse(dateDate);
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            c.add(field, amount);
            return sdf.format(c.getTime());
        } catch (Exception ex) {
            logger.error(ex.getMessage());
        }
        return null;
    }

    /**
     * 字符串转换日期
     *
     * @param dateDate 起息日期
     * @return
     */
    public static String DateToString(String dateDate) {
        try {
            Date date = new SimpleDateFormat("yyyyMMdd").parse(dateDate);
            return new SimpleDateFormat("yyyy-MM-dd").format(date);
        } catch (Exception ex) {
            logger.error(ex.getMessage());
        }
        return null;
    }

    /**
     * 获得指定月份最后一天
     */
    public static String getLastDate(String deprDateDay) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(stringToDate(deprDateDay));
        calendar.add(Calendar.MONTH, 1);
        calendar.add(Calendar.DATE, -1);
        Date date = calendar.getTime();
        return dateToString(date, "yyyy-MM-dd");
    }

    /**
     * 比较两个日期的大小
     *
     * @param DATE1
     * @param DATE2
     * @return
     */
    public static int compare_date(String DATE1, String DATE2) {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date dt1 = df.parse(DATE1);
            Date dt2 = df.parse(DATE2);
            if (dt1.getTime() > dt2.getTime()) {
                return 1;
            } else if (dt1.getTime() < dt2.getTime()) {
                return -1;
            } else {
                return 0;
            }
        } catch (Exception exception) {
            logger.error(exception.getMessage());
        }
        return 0;
    }

    public static Integer dayNum(Integer year) {
        if (year == 0) {
            return LocalDate.now().lengthOfYear();
        } else {
            return LocalDate.of(year, 1, 1).lengthOfYear();
        }
    }

    /**
     * 获得两个日期之间的天数
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static Long getBetweenDays(String startDate, String endDate) {
        return (stringToDate(endDate).getTime() - stringToDate(startDate).getTime()) / (1000 * 60 * 60 * 24);
    }

    /**
     * 获取两个日期相差的月份
     *
     * @param DATE1
     * @param DATE2
     * @return
     */
    public static int compare_date_month(String DATE1, String DATE2) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM");
        YearMonth dt1 = YearMonth.parse(DATE1, df);
        YearMonth dt2 = YearMonth.parse(DATE2, df);
        int resultM = dt2.getMonthValue() - dt1.getMonthValue();
        int resultY = dt2.getYear() - dt1.getYear();
        return resultM + resultY;
    }

    /**
     * 获得当前日期前几天
     *
     * @return
     */
    public static String getLastDayDate(String dates, int amount) throws ParseException {
        SimpleDateFormat sdm = new SimpleDateFormat("yyyy-MM-dd");
        Date date = sdm.parse(dates);
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DATE, -amount);
        String nextDay = sdm.format(cal.getTime());
        return nextDay;
    }

    /**
     * 获得当前月份的最后一天
     *
     * @return
     */
    public static String getCurrMonthLastDay() throws ParseException {
        SimpleDateFormat farmat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        String lastDay = farmat.format(cal.getTime());
        return lastDay;
    }

    /**
     * 根据传入日期 返回XX-XX-XX 23:59:59
     *
     * @param date 日期
     * @return
     */
    public static Date getDateLastTime(String date) {
        Date lastTime = new Date();
        if (ObjectUtils.isEmpty(date)) {
            return lastTime;
        }
        try {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
            DateFormat dateFormat = new SimpleDateFormat(DATE_TIME_FORMAT);
            String endDate = formatter.format(dateFormat.parse(date));
            lastTime = dateFormat.parse(endDate);
        } catch (Exception ex) {
            logger.info("异常信息：" + ex.getMessage());
        }
        return lastTime;
    }

    /**
     * 是否是闰年
     *
     * @param years 年份
     * @return
     */
    public static boolean getLeapYear(String years) {
        Scanner scanner = new Scanner(years);
        long year = scanner.nextLong();
        if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
            return true;
        } else {
            return false;
        }
    }

    public static String getLastDay() {
        LocalDate lastDate = LocalDate.now().minusDays(1);
        return lastDate.format(DateTimeFormatter.ofPattern(DATE_SIMP_FORMAT));
    }

    public static LocalDateTime getCurrentLocalDateTime() {
        return LocalDateTime.now();
    }

    public static Date localDateTimeToDate(LocalDateTime localDateTime) {
        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
        Instant instant = zonedDateTime.toInstant();
        return Date.from(instant);
    }

    public static LocalDateTime dateToLocalDateTime(Date date) {
        Instant instant = date.toInstant();
        ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());
        return zonedDateTime.toLocalDateTime();
    }
}
